package cn.jett.domain.strategy.service.rule.tree.factory.engine.impl;

import cn.jett.domain.strategy.model.valobj.RuleTreeNodeLineVO;
import cn.jett.domain.strategy.model.valobj.RuleTreeNodeVO;
import cn.jett.domain.strategy.model.valobj.RuleTreeVO;
import cn.jett.domain.strategy.model.vo.RuleLogicCheckTypeVO;
import cn.jett.domain.strategy.service.rule.tree.ILogicTreeNode;
import cn.jett.domain.strategy.service.rule.tree.factory.DefaultTreeFactory;
import cn.jett.domain.strategy.service.rule.tree.factory.engine.IDecisionTreeEngine;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;

/**
 * @Author 战斗天使
 * @Description 决策树引擎
 * @Date 2024/6/20
 */
@Slf4j
public class DecisionTreeEngine implements IDecisionTreeEngine {

    /**
     * 规则处理节点集合
     */
    private final Map<String, ILogicTreeNode> logicTreeNodeGroup;

    /**
     * 规则树
     */
    private final RuleTreeVO ruleTreeVO;

    /**
     * 构造规则树引擎
     * @param logicTreeNodeGroup 规则树节点集合
     * @param ruleTreeVO 规则树VO
     */
    public DecisionTreeEngine(Map<String, ILogicTreeNode> logicTreeNodeGroup, RuleTreeVO ruleTreeVO) {
        this.logicTreeNodeGroup = logicTreeNodeGroup;
        this.ruleTreeVO = ruleTreeVO;
    }

    /**
     * 调用规则处理节点进行处理
     * @param userId 用户id
     * @param strategyId 策略id
     * @param awardId 奖品id
     * @return
     */
    @Override
    public DefaultTreeFactory.StrategyAwardVO process(String userId, Long strategyId, Integer awardId) {
        DefaultTreeFactory.StrategyAwardVO strategyAwardVO = null;
        //获取根节点名作为当前节点名
        String nextNode = ruleTreeVO.getTreeRootRuleNode();
        //该规则树节点集合
        Map<String, RuleTreeNodeVO> treeNodeMap = ruleTreeVO.getTreeNodeMap();
        //获取当前节点
        RuleTreeNodeVO ruleTreeNode = treeNodeMap.get(nextNode);
        while (null != nextNode){
            ILogicTreeNode logicTreeNode = logicTreeNodeGroup.get(ruleTreeNode.getRuleKey());
            String ruleValue = ruleTreeNode.getRuleValue();
            DefaultTreeFactory.TreeActionEntity treeActionEntity = logicTreeNode.logic(userId, strategyId, awardId,ruleValue);
            RuleLogicCheckTypeVO actionType = treeActionEntity.getRuleLogicCheckType();
            strategyAwardVO = treeActionEntity.getStrategyAwardVO();
            log.info("决策树引擎：treeName:{},treeId:{},node:{},code:{}",ruleTreeVO.getTreeName(),ruleTreeVO.getTreeId(),nextNode,actionType.getCode());
            nextNode = nextNode(actionType.getCode(),ruleTreeNode.getTreeNodeLineVOList());
            ruleTreeNode = treeNodeMap.get(nextNode);
        }
        return strategyAwardVO;
    }

    /**
     * 处理规则节点的传递
     * @param matterValue 上一个规则处理后的状态码
     * @param ruleTreeNodeLineVOList 节点边集合
     * @return
     */
    private String nextNode(String matterValue, List<RuleTreeNodeLineVO> ruleTreeNodeLineVOList){
        if (null == ruleTreeNodeLineVOList || ruleTreeNodeLineVOList.isEmpty()){
            return null;
        }
        for (RuleTreeNodeLineVO nodeLine:ruleTreeNodeLineVOList) {
            if (decisionLogic(matterValue,nodeLine)){
                return nodeLine.getRuleNodeTo();
            }
        }
        return null;
    }

    /**
     * 处理规则树走向
     * @param matterValue 上一个规则处理后的状态码
     * @param nodeLine 上一个节点的边
     * @return
     */
    public boolean decisionLogic(String matterValue, RuleTreeNodeLineVO nodeLine) {
        switch (nodeLine.getRuleLimitType()) {
            case EQUAL:
                return matterValue.equals(nodeLine.getRuleLimitValue().getCode());
            case GT:
            case LT:
            case GE:
            case LE:
            default:
                return false;
        }
    }
}
